#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Author          : ricsy
@File            : sphinx-icon.py
@Create Time     : 2025/6/9 21:11
@Last Modified   :
@Description     : 图标指令
"""
import random

from docutils import nodes
from docutils.parsers.rst import Directive
from docutils.parsers.rst.directives import choice, unchanged
from ipywidgets import widgets

from extensions.common import validate_bool
from sphinx.application import Sphinx


class IconDirective(Directive):
    """图标指令"""

    required_arguments = 0
    optional_arguments = 0
    final_argument_whitespace = True
    has_content = False
    option_spec = {
        "logobg": unchanged,
        "logocolor": unchanged,
        "logosize": lambda x: choice(x, ["small", "medium", "large"]),
        "logobrand": unchanged,
        "titlecolor": unchanged,
        "title": unchanged,
        "link": unchanged,
        "size": lambda x: choice(x, ["small", "medium", "large"]),
        "tooltip": unchanged,
        "tooltippos": lambda x: choice(x, ["auto", "top", "bottom", "left", "right"]),
        "radius": unchanged,
        "shadow": validate_bool,
        "animation": lambda x: choice(x, ["pulse", "float", "spin", "none"]),
    }

    # 默认选项
    DEFAULT_OPTIONS = {
        "logobg": {
            "value": "#41bf46",
            "widget": widgets.ColorPicker,
            "desc": "logo背景",
        },
        "logocolor": {
            "value": "#ffffff",
            "widget": widgets.ColorPicker,
            "desc": "logo颜色",
        },
        "logosize": {
            "value": 1,
            "widget": widgets.FloatSlider,
            "desc": "logo尺寸",
            "params": {
                "min": 0,
                "max": 5.0,
                "step": 0.1,
                "readout_format": ".1f",
            },
        },
        "logobrand": {"value": "", "widget": widgets.Text, "desc": "logo标识"},
        "titlecolor": {
            "value": "#48566b",
            "widget": widgets.ColorPicker,
            "desc": "标题颜色",
        },
        "title": {"value": "", "widget": widgets.Text, "desc": "标题文本"},
        "link": {"value": "", "widget": widgets.Text, "desc": "链接地址"},
        "size": {
            "value": "medium",
            "widget": widgets.Dropdown,
            "desc": "图标尺寸",
            "options": option_spec.get("size").__code__.co_consts[1],
        },
        "tooltip": {
            "value": "",
            "widget": widgets.Textarea,
            "desc": "悬浮提示",
        },
        "tooltippos": {
            "value": "auto",
            "widget": widgets.Dropdown,
            "desc": "提示位置",
            "options": option_spec.get("tooltippos").__code__.co_consts[1],
        },
        "radius": {
            "value": 50,
            "widget": widgets.FloatSlider,
            "desc": "圆角半径",
            "params": {"min": 0, "max": 50.0, "step": 0.1, "readout_format": ".1f"},
        },
        "shadow": {"value": False, "widget": widgets.Checkbox, "desc": "显示阴影"},
        "animation": {
            "value": "none",
            "widget": widgets.Dropdown,
            "desc": "动画效果",
            "options": option_spec.get("animation").__code__.co_consts[1],
        },
    }

    def get_default_value(self):
        return {k: v["value"] for k, v in self.DEFAULT_OPTIONS.items()}

    def run(self):
        # 生成随机 ID 确保唯一性
        icon_id = f"icon-{random.randint(1000, 9999)}"

        # 获取参数
        options = {**self.get_default_value(), **self.options}
        has_shadow = "shadow" in self.options

        # 处理链接（URL编码）
        link = options["link"].strip()
        if link:
            link_attr = f'href="{link}" target="_blank" rel="noopener noreferrer"'
            container_tag = "a"
        else:
            link_attr = ""
            container_tag = "div"

        # 提示语：内容为空不显示
        normalize_tooltip = (
            options["tooltip"].strip() if options["tooltip"].strip() else ""
        )
        tooltip_position = options["tooltippos"].strip().lower()

        # 构建HTML
        html_content = f"""
            <{container_tag} class="icon-wrapper text-decoration-none" {link_attr}>
                <div id="{icon_id}"
                    class="icon-circle {options["size"]} {options["animation"]}" 
                    style="--icon-logo-bg: {options["logobg"]}; --logo-radius: {options["radius"]}%;"
                    data-bs-toggle="tooltip" data-bs-placement="{tooltip_position}" title="{normalize_tooltip}"
                >
                    <span class="icon-logo" style="--logo-color: {options["logocolor"]} --logo-size: {options["logosize"]}">{options["logobrand"]}</span>
                </div>
                {f'<div class="icon-title" style="--icon-title-color: {options["titlecolor"]}">{options["title"]}</div>' if options["title"] else ''}
            </{container_tag}>
        """

        # 添加阴影类
        if has_shadow:
            html_content = html_content.replace("icon-circle", "icon-circle has-shadow")

        return [nodes.raw("", html_content, format="html")]


def setup(app: Sphinx):
    app.add_directive("icon", IconDirective)
    app.add_css_file("extensions/css/icon.css")
